package it.antonio.ilpizze.db.index.hash.file;

import it.antonio.ilpizze.db.index.hash.Element;
import it.antonio.ilpizze.db.index.utils.FPerst;
import it.antonio.ilpizze.db.index.utils.FilePointer;
import it.antonio.ilpizze.db.io.IOConstants;
import it.antonio.ilpizze.db.io.IOFile;

public class FileElement<K, V> implements Element<K, V>, FilePointer, IOConstants{
	
	/*
	 *  hash|key|value|next
	 */
	
	private IOFile file;
	private long position;
	private FPerst<K> keyPersister;
	private FPerst<V> valuePersister;
	
	public FileElement(IOFile file, long position, FPerst<K> keyPersister, FPerst<V> valuePersister) {
		this.file = file;
		this.position = position;
		this.keyPersister = keyPersister;
		this.valuePersister = valuePersister;
	}
	
	
	@Override
	public K key() {
		file.position(position + SIZE_INT);
		return keyPersister.read(file);
	}

	@Override
	public V value() {
		file.position(position + SIZE_INT + keyPersister.space());
		return valuePersister.read(file);
	}

	@Override
	public void value(V value) {
		file.position(position + SIZE_INT + keyPersister.space());
		valuePersister.persist(file, value);
	}
	@Override
	public int hash() {
		file.position(position);
		return file.readInt();
	}


	@Override
	public Element<K, V> next() {
		file.position(position + SIZE_INT + keyPersister.space() + valuePersister.space());
		
		long position = file.readLong();
		if(position != -1){
			return new FileElement<K, V>(file, position, keyPersister, valuePersister);	
		} else {
			return null;
		}
		
	}


	@Override
	public void next(Element<K, V> e) {
		file.position(position + SIZE_INT + keyPersister.space() + valuePersister.space());
		
		if(e == null){
			file.writeLong(-1);	
		} else {
			FileElement<K, V> fileEntry = (FileElement<K, V>) e;
			file.writeLong(fileEntry.position());	
		}
	}
	
	@Override
	public long position() {
		return position;
	}
	
	@Override
	public long space() {
		return  SIZE_INT + keyPersister.space() + valuePersister.space() +SIZE_LONG;
	}

	@Override
	public String toString() {
		return "FileElement[pos=" + position+"]";
	}

	
}
